home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / src.zoo / src / oblit / blit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-24  |  26.3 KB  |  934 lines

  1. /*                        Copyright (c) 1987 Bellcore
  2.  *                            All Rights Reserved
  3.  *       Permission is granted to copy or use this program, EXCEPT that it
  4.  *       may not be sold for profit, the copyright notice must be reproduced
  5.  *       on copies, and credit should be given to Bellcore where it is due.
  6.  *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7.  */
  8. /*    $Header: blit.c,v 4.1 88/06/21 13:07:59 bianchi Exp $
  9.     $Source: /tmp/mgrsrc/src/oblit/RCS/blit.c,v $
  10. */
  11. static char    RCSid_[] = "$Source: /tmp/mgrsrc/src/oblit/RCS/blit.c,v $$Revision: 4.1 $";
  12.  
  13. /*  SUN-2 bitblit code */
  14.  
  15. #include "bitmap.h"
  16.  
  17. /*
  18.  * your standard unrolled-loop (I don't think this buys much)
  19.  */
  20.  
  21. #define LOOP(n,s) {                \
  22.     register int cnt;                \
  23.     for (cnt=(n); cnt>=16; cnt-=16) {        \
  24.        s;s;s;s;s;s;s;s;s;s;s;s;s;s;s;s;        \
  25.        }                    \
  26.     switch (cnt) {                \
  27.        case 15: s; case 14: s; case 13: s; case 12: s;    \
  28.        case 11: s; case 10: s; case  9: s; case  8: s;    \
  29.        case  7: s; case  6: s; case  5: s; case  4: s;    \
  30.        case  3: s; case  2: s; case  1: s;         \
  31.        }                        \
  32.     }
  33.  
  34. /*
  35.  * A funny unrolled-loop: even and odd cases differ
  36.  */
  37.  
  38. #define LOOP2(n,s1,s2) {                 \
  39.     register int cnt;                    \
  40.     for (cnt=(n); cnt>=16; cnt-=16)    {        \
  41.        s1;s2;s1;s2;s1;s2;s1;s2;s1;s2;s1;s2;s1;s2;s1;s2;    \
  42.        }                        \
  43.     switch (cnt) {                    \
  44.        case 15: s1;s2; case 13: s1;s2; case 11: s1;s2;     \
  45.        case  9: s1;s2; case  7: s1;s2; case  5: s1;s2;    \
  46.        case  3: s1;s2; case  1: s1;            \
  47.           break;                    \
  48.        case 14: s1;s2; case 12: s1;s2; case 10: s1;s2;    \
  49.        case  8: s1;s2; case  6: s1;s2; case  4: s1;s2;    \
  50.        case  2: s1;s2; case  0: src=srcx;        \
  51.        }                        \
  52.     }
  53.  
  54. #define lsrc    ((unsigned long *)src)
  55. #define lsrcx    ((unsigned long *)srcx)
  56.  
  57. /*
  58.  *  General memory-to-memory rasterop
  59.  */
  60.  
  61. mem_rop(dest, dx, dy, width, height, func, source, sx, sy)
  62. int sx, sy, dx, dy;        /* properly clipped source and dest */
  63. int width, height;        /* rectangle to be transferred */
  64. BITMAP *source, *dest;        /* bit map pointers */
  65. int func;            /* rasterop function */
  66.  
  67. {
  68.    int dwwidth = BIT_LINE(dest);
  69.    int swwidth = 0;
  70.    int xs, ys;
  71.    int xd, yd;
  72.    unsigned short *sbase = (unsigned short *) 0;
  73.    unsigned short *dbase = (dest->data);
  74.  
  75.    /* clipping, should already be done ? */
  76.  
  77.    {
  78.       register int t;
  79.  
  80.       if (width < 0)
  81.      dx += width, width = -width;
  82.       if (height < 0)
  83.      dy += height, height = -height;
  84.       if (dx < 0) {
  85.      if (source)
  86.         sx -= dx;
  87.      width += dx, dx = 0;
  88.       }
  89.  
  90.       if (dy < 0) {
  91.      if (source)
  92.         sy -= dy;
  93.      height += dy, dy = 0;
  94.       }
  95.  
  96.       if (source) {
  97.      if (sx < 0)
  98.         dx -= sx, width += sx, sx = 0;
  99.      if (sy < 0)
  100.         dy -= sy, height += sy, sy = 0;
  101.      if ((t = sx + width - source->wide) > 0)
  102.         width -= t;
  103.      if ((t = sy + height - source->high) > 0)
  104.         height -= t;
  105.  
  106.      swwidth = BIT_LINE(source);
  107.      xs = sx + source->x0, ys = sy + source->y0;
  108.      sbase = (source->data);
  109.       }
  110.  
  111.       if ((t = dx + width - dest->wide) > 0)
  112.      width -= t;
  113.       if ((t = dy + height - dest->high) > 0)
  114.      height -= t;
  115.  
  116.       if (width < 1 || height < 1)
  117.      return;
  118.    }
  119.  
  120.    /*********/
  121.  
  122.    xd = dx + dest->x0, yd = dy + dest->y0;
  123.    func = OPCODE(func);
  124.  
  125.    if (!source) {        /* no source bitmap */
  126.  
  127.       register unsigned long *dst =
  128.       (unsigned long *) (dbase + yd * dwwidth + (xd >> 4));
  129.       register unsigned int mask1 =
  130.       ((unsigned long) 0xFFFFFFFF) >> (xd & 15);
  131.       register unsigned int h_cnt =
  132.       ((xd + width - 1) - ((xd & ~15)) >> 5) + 1;
  133.       register unsigned int mask2 =
  134.       0xFFFFFFFF << (31 - (((xd + width - 1) - (xd & ~15)) & 31));
  135.       register unsigned int d_incr =
  136.       (dwwidth << 1) - (h_cnt << 2);
  137.       register unsigned int v_cnt;
  138.  
  139.       if (h_cnt > 1)        /* multi-line bitblit */
  140.      switch (func) {    /* no source */
  141.         case OPCODE(0):
  142.         case OPCODE(~(DST | SRC)):
  143.         case OPCODE(DST & ~SRC):
  144.         case OPCODE(~SRC):    /* no source multi-word blit */
  145.            for (v_cnt = height; v_cnt > 0; v_cnt--) {
  146.           *dst++ = *dst & ~mask1;
  147.           LOOP((h_cnt) - 2, *dst++ = 0);
  148.           *dst++ = *dst & ~mask2;
  149.           (int) dst += d_incr;
  150.            }
  151.  
  152.            break;
  153.         case OPCODE(~DST & SRC):
  154.         case OPCODE(~DST):
  155.         case OPCODE(DST ^ SRC):
  156.         case OPCODE(~(DST & SRC)):    /* no source multi-word blit */
  157.            for (v_cnt = height; v_cnt > 0; v_cnt--) {
  158.           *dst++ = *dst ^ mask1;
  159.           LOOP((h_cnt) - 2, *dst++ = ~*dst);
  160.           *dst++ = *dst ^ mask2;
  161.           (int) dst += d_incr;
  162.            }
  163.  
  164.            break;
  165.         case OPCODE(SRC):
  166.         case OPCODE(~DST | SRC):
  167.         case OPCODE(DST | SRC):
  168.         case OPCODE(~0):    /* no source multi-word blit */
  169.            for (v_cnt = height; v_cnt > 0; v_cnt--) {
  170.           *dst++ = ((*dst) | (mask1));
  171.           LOOP((h_cnt) - 2, *dst++ = ~0);
  172.           *dst++ = ((*dst) | (mask2));
  173.           (int) dst += d_incr;
  174.            }
  175.  
  176.            break;
  177.      }
  178.  
  179.       else {            /* single line bit-blit */
  180.      mask1 &= mask2;
  181.      switch (func) {    /* no source */
  182.         case OPCODE(0):
  183.         case OPCODE(~(DST | SRC)):
  184.         case OPCODE(DST & ~SRC):
  185.         case OPCODE(~SRC):    /* no source single-word blit */
  186.            for (v_cnt = height; v_cnt > 0; v_cnt--) {
  187.           *dst++ = *dst & ~mask1;
  188.           (int) dst += d_incr;
  189.            }
  190.  
  191.            break;
  192.         case OPCODE(~DST & SRC):
  193.         case OPCODE(~DST):
  194.         case OPCODE(DST ^ SRC):
  195.         case OPCODE(~(DST & SRC)):    /* no source single-word blit */
  196.            for (v_cnt = height; v_cnt > 0; v_cnt--) {
  197.           *dst++ = *dst ^ mask1;
  198.           (int) dst += d_incr;
  199.            }
  200.  
  201.            break;
  202.         case OPCODE(SRC):
  203.         case OPCODE(~DST | SRC):
  204.         case OPCODE(DST | SRC):
  205.         case OPCODE(~0):    /* no source single-word blit */
  206.            for (v_cnt = height; v_cnt > 0; v_cnt--) {
  207.           *dst++ = ((*dst) | (mask1));
  208.           (int) dst += d_incr;
  209.            }
  210.  
  211.            break;
  212.      }
  213.  
  214.       }
  215.  
  216.    }
  217.  
  218.    /* source (op) dest bitmap */
  219.  
  220.    else {
  221.       unsigned int lmask =
  222.       0xFFFF >> (xd & 15);    /* mask for left edge */
  223.       unsigned int h_cnt =
  224.       ((xd + width - 1) >> 4) - (xd >> 4) + 1;    /* shorts in dest */
  225.       unsigned int rmask =
  226.       0xFFFF << (15 - ((xd + width - 1) & 15));    /* mask for right edge */
  227.  
  228.       register unsigned short *src =
  229.       sbase + ys * swwidth + (xs >> 4);    /* source */
  230.       register unsigned short *srcx;    /* source alternate */
  231.       register unsigned short *dst =
  232.       dbase + yd * dwwidth + (xd >> 4);    /* destination */
  233.       register unsigned int mask1, mask2;    /* masks */
  234.       register unsigned int shift;    /* shift count */
  235.       int s_incr, d_incr;    /* how to get line to line */
  236.       int v_cnt;        /* number of lines */
  237.  
  238.       if ((xs & 15) > (xd & 15))
  239.      shift = 16 - (xs & 15) + (xd & 15);
  240.       else
  241.      shift = (xd & 15) - (xs & 15), src -= 1;
  242.  
  243.       if (yd < ys)
  244.      s_incr = swwidth, d_incr = dwwidth;    /* top to bottom */
  245.       else
  246.      s_incr = -swwidth, d_incr = -dwwidth,
  247.         src += (height - 1) * swwidth,
  248.         dst += (height - 1) * dwwidth;    /* bottom to top */
  249.  
  250.       if (xd < xs) {        /* left to right */
  251.      s_incr -= h_cnt + 1, d_incr -= h_cnt;
  252.      if (h_cnt > 1) {
  253.         mask1 = lmask, mask2 = rmask;
  254.         {
  255.            switch (func) {
  256.           case OPCODE(~(DST | SRC)):    /* left->right multi-word blit */
  257.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  258.             srcx = src;
  259.             srcx++;
  260.             *dst++ = ~(*dst | *lsrc++ >> shift) & mask1 | *dst & ~mask1;
  261.             LOOP2((h_cnt) - 2, *dst++ = ~(*dst | *lsrcx++ >> shift), *dst++ = ~(*dst | *lsrc++ >> shift));
  262.             *dst++ = ~(*dst | *lsrc++ >> shift) & mask2 | *dst & ~mask2;
  263.             src += s_incr;
  264.             dst += d_incr;
  265.              }
  266.  
  267.              break;
  268.           case OPCODE(DST & ~SRC):    /* left->right multi-word blit */
  269.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  270.             srcx = src;
  271.             srcx++;
  272.             *dst++ = *dst & ~*lsrc++ >> shift & mask1 | *dst & ~mask1;
  273.             LOOP2((h_cnt) - 2, *dst++ = *dst & ~*lsrcx++ >> shift, *dst++ = *dst & ~*lsrc++ >> shift);
  274.             *dst++ = *dst & ~*lsrc++ >> shift & mask2 | *dst & ~mask2;
  275.             src += s_incr;
  276.             dst += d_incr;
  277.              }
  278.  
  279.              break;
  280.           case OPCODE(~SRC):    /* left->right multi-word blit */
  281.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  282.             srcx = src;
  283.             srcx++;
  284.             *dst++ = ~*lsrc++ >> shift & mask1 | *dst & ~mask1;
  285.             LOOP2((h_cnt) - 2, *dst++ = ~*lsrcx++ >> shift, *dst++ = ~*lsrc++ >> shift);
  286.             *dst++ = ~*lsrc++ >> shift & mask2 | *dst & ~mask2;
  287.             src += s_incr;
  288.             dst += d_incr;
  289.              }
  290.  
  291.              break;
  292.           case OPCODE(~DST & SRC):    /* left->right multi-word blit */
  293.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  294.             srcx = src;
  295.             srcx++;
  296.             *dst++ = ~*dst & *lsrc++ >> shift & mask1 | *dst & ~mask1;
  297.             LOOP2((h_cnt) - 2, *dst++ = ~*dst & *lsrcx++ >> shift, *dst++ = ~*dst & *lsrc++ >> shift);
  298.             *dst++ = ~*dst & *lsrc++ >> shift & mask2 | *dst & ~mask2;
  299.             src += s_incr;
  300.             dst += d_incr;
  301.              }
  302.  
  303.              break;
  304.           case OPCODE(DST ^ SRC):    /* left->right multi-word blit */
  305.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  306.             srcx = src;
  307.             srcx++;
  308.             *dst++ = *dst ^ *lsrc++ >> shift & mask1 | *dst & ~mask1;
  309.             LOOP2((h_cnt) - 2, *dst++ = *dst ^ *lsrcx++ >> shift, *dst++ = *dst ^ *lsrc++ >> shift);
  310.             *dst++ = *dst ^ *lsrc++ >> shift & mask2 | *dst & ~mask2;
  311.             src += s_incr;
  312.             dst += d_incr;
  313.              }
  314.  
  315.              break;
  316.           case OPCODE(~(DST & SRC)):    /* left->right multi-word blit */
  317.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  318.             srcx = src;
  319.             srcx++;
  320.             *dst++ = ~(*dst & *lsrc++ >> shift) & mask1 | *dst & ~mask1;
  321.             LOOP2((h_cnt) - 2, *dst++ = ~(*dst & *lsrcx++ >> shift), *dst++ = ~(*dst & *lsrc++ >> shift));
  322.             *dst++ = ~(*dst & *lsrc++ >> shift) & mask2 | *dst & ~mask2;
  323.             src += s_incr;
  324.             dst += d_incr;
  325.              }
  326.  
  327.              break;
  328.           case OPCODE(DST & SRC):    /* left->right multi-word blit */
  329.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  330.             srcx = src;
  331.             srcx++;
  332.             *dst++ = *dst & *lsrc++ >> shift & mask1 | *dst & ~mask1;
  333.             LOOP2((h_cnt) - 2, *dst++ = *dst & *lsrcx++ >> shift, *dst++ = *dst & *lsrc++ >> shift);
  334.             *dst++ = *dst & *lsrc++ >> shift & mask2 | *dst & ~mask2;
  335.             src += s_incr;
  336.             dst += d_incr;
  337.              }
  338.  
  339.              break;
  340.           case OPCODE(~(DST ^ SRC)):    /* left->right multi-word blit */
  341.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  342.             srcx = src;
  343.             srcx++;
  344.             *dst++ = ~(*dst ^ *lsrc++ >> shift) & mask1 | *dst & ~mask1;
  345.             LOOP2((h_cnt) - 2, *dst++ = ~(*dst ^ *lsrcx++ >> shift), *dst++ = ~(*dst ^ *lsrc++ >> shift));
  346.             *dst++ = ~(*dst ^ *lsrc++ >> shift) & mask2 | *dst & ~mask2;
  347.             src += s_incr;
  348.             dst += d_incr;
  349.              }
  350.  
  351.              break;
  352.           case OPCODE(DST | ~SRC):    /* left->right multi-word blit */
  353.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  354.             srcx = src;
  355.             srcx++;
  356.             *dst++ = *dst | ~*lsrc++ >> shift & mask1 | *dst & ~mask1;
  357.             LOOP2((h_cnt) - 2, *dst++ = *dst | ~*lsrcx++ >> shift, *dst++ = *dst | ~*lsrc++ >> shift);
  358.             *dst++ = *dst | ~*lsrc++ >> shift & mask2 | *dst & ~mask2;
  359.             src += s_incr;
  360.             dst += d_incr;
  361.              }
  362.  
  363.              break;
  364.           case OPCODE(SRC):    /* left->right multi-word blit */
  365.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  366.             srcx = src;
  367.             srcx++;
  368.             *dst++ = *lsrc++ >> shift & mask1 | *dst & ~mask1;
  369.             LOOP2((h_cnt) - 2, *dst++ = *lsrcx++ >> shift, *dst++ = *lsrc++ >> shift);
  370.             *dst++ = *lsrc++ >> shift & mask2 | *dst & ~mask2;
  371.             src += s_incr;
  372.             dst += d_incr;
  373.              }
  374.  
  375.              break;
  376.           case OPCODE(~DST | SRC):    /* left->right multi-word blit */
  377.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  378.             srcx = src;
  379.             srcx++;
  380.             *dst++ = ~*dst | *lsrc++ >> shift & mask1 | *dst & ~mask1;
  381.             LOOP2((h_cnt) - 2, *dst++ = ~*dst | *lsrcx++ >> shift, *dst++ = ~*dst | *lsrc++ >> shift);
  382.             *dst++ = ~*dst | *lsrc++ >> shift & mask2 | *dst & ~mask2;
  383.             src += s_incr;
  384.             dst += d_incr;
  385.              }
  386.  
  387.              break;
  388.           case OPCODE(DST | SRC):    /* left->right multi-word blit */
  389.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  390.             srcx = src;
  391.             srcx++;
  392.             *dst++ = *dst | *lsrc++ >> shift & mask1 | *dst & ~mask1;
  393.             LOOP2((h_cnt) - 2, *dst++ = *dst | *lsrcx++ >> shift, *dst++ = *dst | *lsrc++ >> shift);
  394.             *dst++ = *dst | *lsrc++ >> shift & mask2 | *dst & ~mask2;
  395.             src += s_incr;
  396.             dst += d_incr;
  397.              }
  398.  
  399.              break;    /* these should never be called - use no source case */
  400.           case OPCODE(0):    /* left->right multi-word blit */
  401.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  402.             *dst++ = 0 & mask1 | *dst & ~mask1;
  403.             LOOP2((h_cnt) - 2, *dst++ = 0, *dst++ = 0);
  404.             *dst++ = 0 & mask2 | *dst & ~mask2;
  405.             dst += d_incr;
  406.              }
  407.  
  408.              break;
  409.           case OPCODE(~DST):    /* left->right multi-word blit */
  410.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  411.             *dst++ = ~*dst & mask1 | *dst & ~mask1;
  412.             LOOP2((h_cnt) - 2, *dst++ = ~*dst, *dst++ = ~*dst);
  413.             *dst++ = ~*dst & mask2 | *dst & ~mask2;
  414.             dst += d_incr;
  415.              }
  416.  
  417.              break;
  418.           case OPCODE(~0):    /* left->right multi-word blit */
  419.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  420.             *dst++ = ~0 & mask1 | *dst & ~mask1;
  421.             LOOP2((h_cnt) - 2, *dst++ = ~0, *dst++ = ~0);
  422.             *dst++ = ~0 & mask2 | *dst & ~mask2;
  423.             dst += d_incr;
  424.              }
  425.  
  426.              break;
  427.           case OPCODE(DST):
  428.              break;
  429.            }
  430.  
  431.         }
  432.  
  433.      }
  434.  
  435.      else {
  436.         mask1 = lmask & rmask;
  437.         {
  438.            switch (func) {
  439.           case OPCODE(~(DST | SRC)):    /* left->right single-word blit */
  440.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  441.             srcx = src;
  442.             srcx++;
  443.             *dst++ = ~(*dst | *lsrc++ >> shift) & mask1 | *dst & ~mask1;
  444.             src += s_incr;
  445.             dst += d_incr;
  446.              }
  447.  
  448.              break;
  449.           case OPCODE(DST & ~SRC):    /* left->right single-word blit */
  450.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  451.             srcx = src;
  452.             srcx++;
  453.             *dst++ = *dst & ~*lsrc++ >> shift & mask1 | *dst & ~mask1;
  454.             src += s_incr;
  455.             dst += d_incr;
  456.              }
  457.  
  458.              break;
  459.           case OPCODE(~SRC):    /* left->right single-word blit */
  460.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  461.             srcx = src;
  462.             srcx++;
  463.             *dst++ = ~*lsrc++ >> shift & mask1 | *dst & ~mask1;
  464.             src += s_incr;
  465.             dst += d_incr;
  466.              }
  467.  
  468.              break;
  469.           case OPCODE(~DST & SRC):    /* left->right single-word blit */
  470.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  471.             srcx = src;
  472.             srcx++;
  473.             *dst++ = ~*dst & *lsrc++ >> shift & mask1 | *dst & ~mask1;
  474.             src += s_incr;
  475.             dst += d_incr;
  476.              }
  477.  
  478.              break;
  479.           case OPCODE(DST ^ SRC):    /* left->right single-word blit */
  480.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  481.             srcx = src;
  482.             srcx++;
  483.             *dst++ = *dst ^ *lsrc++ >> shift & mask1 | *dst & ~mask1;
  484.             src += s_incr;
  485.             dst += d_incr;
  486.              }
  487.  
  488.              break;
  489.           case OPCODE(~(DST & SRC)):    /* left->right single-word blit */
  490.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  491.             srcx = src;
  492.             srcx++;
  493.             *dst++ = ~(*dst & *lsrc++ >> shift) & mask1 | *dst & ~mask1;
  494.             src += s_incr;
  495.             dst += d_incr;
  496.              }
  497.  
  498.              break;
  499.           case OPCODE(DST & SRC):    /* left->right single-word blit */
  500.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  501.             srcx = src;
  502.             srcx++;
  503.             *dst++ = *dst & *lsrc++ >> shift & mask1 | *dst & ~mask1;
  504.             src += s_incr;
  505.             dst += d_incr;
  506.              }
  507.  
  508.              break;
  509.           case OPCODE(~(DST ^ SRC)):    /* left->right single-word blit */
  510.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  511.             srcx = src;
  512.             srcx++;
  513.             *dst++ = ~(*dst ^ *lsrc++ >> shift) & mask1 | *dst & ~mask1;
  514.             src += s_incr;
  515.             dst += d_incr;
  516.              }
  517.  
  518.              break;
  519.           case OPCODE(DST | ~SRC):    /* left->right single-word blit */
  520.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  521.             srcx = src;
  522.             srcx++;
  523.             *dst++ = *dst | ~*lsrc++ >> shift & mask1 | *dst & ~mask1;
  524.             src += s_incr;
  525.             dst += d_incr;
  526.              }
  527.  
  528.              break;
  529.           case OPCODE(SRC):    /* left->right single-word blit */
  530.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  531.             srcx = src;
  532.             srcx++;
  533.             *dst++ = *lsrc++ >> shift & mask1 | *dst & ~mask1;
  534.             src += s_incr;
  535.             dst += d_incr;
  536.              }
  537.  
  538.              break;
  539.           case OPCODE(~DST | SRC):    /* left->right single-word blit */
  540.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  541.             srcx = src;
  542.             srcx++;
  543.             *dst++ = ~*dst | *lsrc++ >> shift & mask1 | *dst & ~mask1;
  544.             src += s_incr;
  545.             dst += d_incr;
  546.              }
  547.  
  548.              break;
  549.           case OPCODE(DST | SRC):    /* left->right single-word blit */
  550.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  551.             srcx = src;
  552.             srcx++;
  553.             *dst++ = *dst | *lsrc++ >> shift & mask1 | *dst & ~mask1;
  554.             src += s_incr;
  555.             dst += d_incr;
  556.              }
  557.  
  558.              break;    /* these should never be called - use no source case */
  559.           case OPCODE(0):    /* left->right single-word blit */
  560.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  561.             *dst++ = 0 & mask1 | *dst & ~mask1;
  562.             dst += d_incr;
  563.              }
  564.  
  565.              break;
  566.           case OPCODE(~DST):    /* left->right single-word blit */
  567.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  568.             *dst++ = ~*dst & mask1 | *dst & ~mask1;
  569.             dst += d_incr;
  570.              }
  571.  
  572.              break;
  573.           case OPCODE(~0):    /* left->right single-word blit */
  574.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  575.             *dst++ = ~0 & mask1 | *dst & ~mask1;
  576.             dst += d_incr;
  577.              }
  578.  
  579.              break;
  580.           case OPCODE(DST):
  581.              break;
  582.            }
  583.  
  584.         }
  585.  
  586.      }
  587.  
  588.       }
  589.  
  590.       else {            /* right to left */
  591.      s_incr += h_cnt + 1, d_incr += h_cnt;
  592.      src += h_cnt - 1, dst += h_cnt - 1;
  593.      if (h_cnt > 1) {
  594.         mask1 = rmask, mask2 = lmask;
  595.         {
  596.            switch (func) {
  597.           case OPCODE(~(DST | SRC)):    /* right->left multi-word blit */
  598.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  599.             srcx = src;
  600.             srcx--;
  601.             *dst-- = ~(*dst | *lsrc-- >> shift) & mask1 | *dst & ~mask1;
  602.             LOOP2((h_cnt) - 2, *dst-- = ~(*dst | *lsrcx-- >> shift), *dst-- = ~(*dst | *lsrc-- >> shift));
  603.             *dst-- = ~(*dst | *lsrc-- >> shift) & mask2 | *dst & ~mask2;
  604.             src += s_incr;
  605.             dst += d_incr;
  606.              }
  607.  
  608.              break;
  609.           case OPCODE(DST & ~SRC):    /* right->left multi-word blit */
  610.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  611.             srcx = src;
  612.             srcx--;
  613.             *dst-- = *dst & ~*lsrc-- >> shift & mask1 | *dst & ~mask1;
  614.             LOOP2((h_cnt) - 2, *dst-- = *dst & ~*lsrcx-- >> shift, *dst-- = *dst & ~*lsrc-- >> shift);
  615.             *dst-- = *dst & ~*lsrc-- >> shift & mask2 | *dst & ~mask2;
  616.             src += s_incr;
  617.             dst += d_incr;
  618.              }
  619.  
  620.              break;
  621.           case OPCODE(~SRC):    /* right->left multi-word blit */
  622.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  623.             srcx = src;
  624.             srcx--;
  625.             *dst-- = ~*lsrc-- >> shift & mask1 | *dst & ~mask1;
  626.             LOOP2((h_cnt) - 2, *dst-- = ~*lsrcx-- >> shift, *dst-- = ~*lsrc-- >> shift);
  627.             *dst-- = ~*lsrc-- >> shift & mask2 | *dst & ~mask2;
  628.             src += s_incr;
  629.             dst += d_incr;
  630.              }
  631.  
  632.              break;
  633.           case OPCODE(~DST & SRC):    /* right->left multi-word blit */
  634.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  635.             srcx = src;
  636.             srcx--;
  637.             *dst-- = ~*dst & *lsrc-- >> shift & mask1 | *dst & ~mask1;
  638.             LOOP2((h_cnt) - 2, *dst-- = ~*dst & *lsrcx-- >> shift, *dst-- = ~*dst & *lsrc-- >> shift);
  639.             *dst-- = ~*dst & *lsrc-- >> shift & mask2 | *dst & ~mask2;
  640.             src += s_incr;
  641.             dst += d_incr;
  642.              }
  643.  
  644.              break;
  645.           case OPCODE(DST ^ SRC):    /* right->left multi-word blit */
  646.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  647.             srcx = src;
  648.             srcx--;
  649.             *dst-- = *dst ^ *lsrc-- >> shift & mask1 | *dst & ~mask1;
  650.             LOOP2((h_cnt) - 2, *dst-- = *dst ^ *lsrcx-- >> shift, *dst-- = *dst ^ *lsrc-- >> shift);
  651.             *dst-- = *dst ^ *lsrc-- >> shift & mask2 | *dst & ~mask2;
  652.             src += s_incr;
  653.             dst += d_incr;
  654.              }
  655.  
  656.              break;
  657.           case OPCODE(~(DST & SRC)):    /* right->left multi-word blit */
  658.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  659.             srcx = src;
  660.             srcx--;
  661.             *dst-- = ~(*dst & *lsrc-- >> shift) & mask1 | *dst & ~mask1;
  662.             LOOP2((h_cnt) - 2, *dst-- = ~(*dst & *lsrcx-- >> shift), *dst-- = ~(*dst & *lsrc-- >> shift));
  663.             *dst-- = ~(*dst & *lsrc-- >> shift) & mask2 | *dst & ~mask2;
  664.             src += s_incr;
  665.             dst += d_incr;
  666.              }
  667.  
  668.              break;
  669.           case OPCODE(DST & SRC):    /* right->left multi-word blit */
  670.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  671.             srcx = src;
  672.             srcx--;
  673.             *dst-- = *dst & *lsrc-- >> shift & mask1 | *dst & ~mask1;
  674.             LOOP2((h_cnt) - 2, *dst-- = *dst & *lsrcx-- >> shift, *dst-- = *dst & *lsrc-- >> shift);
  675.             *dst-- = *dst & *lsrc-- >> shift & mask2 | *dst & ~mask2;
  676.             src += s_incr;
  677.             dst += d_incr;
  678.              }
  679.  
  680.              break;
  681.           case OPCODE(~(DST ^ SRC)):    /* right->left multi-word blit */
  682.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  683.             srcx = src;
  684.             srcx--;
  685.             *dst-- = ~(*dst ^ *lsrc-- >> shift) & mask1 | *dst & ~mask1;
  686.             LOOP2((h_cnt) - 2, *dst-- = ~(*dst ^ *lsrcx-- >> shift), *dst-- = ~(*dst ^ *lsrc-- >> shift));
  687.             *dst-- = ~(*dst ^ *lsrc-- >> shift) & mask2 | *dst & ~mask2;
  688.             src += s_incr;
  689.             dst += d_incr;
  690.              }
  691.  
  692.              break;
  693.           case OPCODE(DST | ~SRC):    /* right->left multi-word blit */
  694.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  695.             srcx = src;
  696.             srcx--;
  697.             *dst-- = *dst | ~*lsrc-- >> shift & mask1 | *dst & ~mask1;
  698.             LOOP2((h_cnt) - 2, *dst-- = *dst | ~*lsrcx-- >> shift, *dst-- = *dst | ~*lsrc-- >> shift);
  699.             *dst-- = *dst | ~*lsrc-- >> shift & mask2 | *dst & ~mask2;
  700.             src += s_incr;
  701.             dst += d_incr;
  702.              }
  703.  
  704.              break;
  705.           case OPCODE(SRC):    /* right->left multi-word blit */
  706.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  707.             srcx = src;
  708.             srcx--;
  709.             *dst-- = *lsrc-- >> shift & mask1 | *dst & ~mask1;
  710.             LOOP2((h_cnt) - 2, *dst-- = *lsrcx-- >> shift, *dst-- = *lsrc-- >> shift);
  711.             *dst-- = *lsrc-- >> shift & mask2 | *dst & ~mask2;
  712.             src += s_incr;
  713.             dst += d_incr;
  714.              }
  715.  
  716.              break;
  717.           case OPCODE(~DST | SRC):    /* right->left multi-word blit */
  718.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  719.             srcx = src;
  720.             srcx--;
  721.             *dst-- = ~*dst | *lsrc-- >> shift & mask1 | *dst & ~mask1;
  722.             LOOP2((h_cnt) - 2, *dst-- = ~*dst | *lsrcx-- >> shift, *dst-- = ~*dst | *lsrc-- >> shift);
  723.             *dst-- = ~*dst | *lsrc-- >> shift & mask2 | *dst & ~mask2;
  724.             src += s_incr;
  725.             dst += d_incr;
  726.              }
  727.  
  728.              break;
  729.           case OPCODE(DST | SRC):    /* right->left multi-word blit */
  730.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  731.             srcx = src;
  732.             srcx--;
  733.             *dst-- = *dst | *lsrc-- >> shift & mask1 | *dst & ~mask1;
  734.             LOOP2((h_cnt) - 2, *dst-- = *dst | *lsrcx-- >> shift, *dst-- = *dst | *lsrc-- >> shift);
  735.             *dst-- = *dst | *lsrc-- >> shift & mask2 | *dst & ~mask2;
  736.             src += s_incr;
  737.             dst += d_incr;
  738.              }
  739.  
  740.              break;    /* these should never be called - use no source case */
  741.           case OPCODE(0):    /* right->left multi-word blit */
  742.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  743.             *dst-- = 0 & mask1 | *dst & ~mask1;
  744.             LOOP2((h_cnt) - 2, *dst-- = 0, *dst-- = 0);
  745.             *dst-- = 0 & mask2 | *dst & ~mask2;
  746.             dst += d_incr;
  747.              }
  748.  
  749.              break;
  750.           case OPCODE(~DST):    /* right->left multi-word blit */
  751.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  752.             *dst-- = ~*dst & mask1 | *dst & ~mask1;
  753.             LOOP2((h_cnt) - 2, *dst-- = ~*dst, *dst-- = ~*dst);
  754.             *dst-- = ~*dst & mask2 | *dst & ~mask2;
  755.             dst += d_incr;
  756.              }
  757.  
  758.              break;
  759.           case OPCODE(~0):    /* right->left multi-word blit */
  760.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  761.             *dst-- = ~0 & mask1 | *dst & ~mask1;
  762.             LOOP2((h_cnt) - 2, *dst-- = ~0, *dst-- = ~0);
  763.             *dst-- = ~0 & mask2 | *dst & ~mask2;
  764.             dst += d_incr;
  765.              }
  766.  
  767.              break;
  768.           case OPCODE(DST):
  769.              break;
  770.            }
  771.  
  772.         }
  773.  
  774.      }
  775.  
  776.      else {
  777.         mask1 = lmask & rmask;
  778.         {
  779.            switch (func) {
  780.           case OPCODE(~(DST | SRC)):    /* right->left single-word blit */
  781.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  782.             srcx = src;
  783.             srcx--;
  784.             *dst-- = ~(*dst | *lsrc-- >> shift) & mask1 | *dst & ~mask1;
  785.             src += s_incr;
  786.             dst += d_incr;
  787.              }
  788.  
  789.              break;
  790.           case OPCODE(DST & ~SRC):    /* right->left single-word blit */
  791.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  792.             srcx = src;
  793.             srcx--;
  794.             *dst-- = *dst & ~*lsrc-- >> shift & mask1 | *dst & ~mask1;
  795.             src += s_incr;
  796.             dst += d_incr;
  797.              }
  798.  
  799.              break;
  800.           case OPCODE(~SRC):    /* right->left single-word blit */
  801.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  802.             srcx = src;
  803.             srcx--;
  804.             *dst-- = ~*lsrc-- >> shift & mask1 | *dst & ~mask1;
  805.             src += s_incr;
  806.             dst += d_incr;
  807.              }
  808.  
  809.              break;
  810.           case OPCODE(~DST & SRC):    /* right->left single-word blit */
  811.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  812.             srcx = src;
  813.             srcx--;
  814.             *dst-- = ~*dst & *lsrc-- >> shift & mask1 | *dst & ~mask1;
  815.             src += s_incr;
  816.             dst += d_incr;
  817.              }
  818.  
  819.              break;
  820.           case OPCODE(DST ^ SRC):    /* right->left single-word blit */
  821.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  822.             srcx = src;
  823.             srcx--;
  824.             *dst-- = *dst ^ *lsrc-- >> shift & mask1 | *dst & ~mask1;
  825.             src += s_incr;
  826.             dst += d_incr;
  827.              }
  828.  
  829.              break;
  830.           case OPCODE(~(DST & SRC)):    /* right->left single-word blit */
  831.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  832.             srcx = src;
  833.             srcx--;
  834.             *dst-- = ~(*dst & *lsrc-- >> shift) & mask1 | *dst & ~mask1;
  835.             src += s_incr;
  836.             dst += d_incr;
  837.              }
  838.  
  839.              break;
  840.           case OPCODE(DST & SRC):    /* right->left single-word blit */
  841.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  842.             srcx = src;
  843.             srcx--;
  844.             *dst-- = *dst & *lsrc-- >> shift & mask1 | *dst & ~mask1;
  845.             src += s_incr;
  846.             dst += d_incr;
  847.              }
  848.  
  849.              break;
  850.           case OPCODE(~(DST ^ SRC)):    /* right->left single-word blit */
  851.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  852.             srcx = src;
  853.             srcx--;
  854.             *dst-- = ~(*dst ^ *lsrc-- >> shift) & mask1 | *dst & ~mask1;
  855.             src += s_incr;
  856.             dst += d_incr;
  857.              }
  858.  
  859.              break;
  860.           case OPCODE(DST | ~SRC):    /* right->left single-word blit */
  861.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  862.             srcx = src;
  863.             srcx--;
  864.             *dst-- = *dst | ~*lsrc-- >> shift & mask1 | *dst & ~mask1;
  865.             src += s_incr;
  866.             dst += d_incr;
  867.              }
  868.  
  869.              break;
  870.           case OPCODE(SRC):    /* right->left single-word blit */
  871.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  872.             srcx = src;
  873.             srcx--;
  874.             *dst-- = *lsrc-- >> shift & mask1 | *dst & ~mask1;
  875.             src += s_incr;
  876.             dst += d_incr;
  877.              }
  878.  
  879.              break;
  880.           case OPCODE(~DST | SRC):    /* right->left single-word blit */
  881.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  882.             srcx = src;
  883.             srcx--;
  884.             *dst-- = ~*dst | *lsrc-- >> shift & mask1 | *dst & ~mask1;
  885.             src += s_incr;
  886.             dst += d_incr;
  887.              }
  888.  
  889.              break;
  890.           case OPCODE(DST | SRC):    /* right->left single-word blit */
  891.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  892.             srcx = src;
  893.             srcx--;
  894.             *dst-- = *dst | *lsrc-- >> shift & mask1 | *dst & ~mask1;
  895.             src += s_incr;
  896.             dst += d_incr;
  897.              }
  898.  
  899.              break;    /* these should never be called - use no source case */
  900.           case OPCODE(0):    /* right->left single-word blit */
  901.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  902.             *dst-- = 0 & mask1 | *dst & ~mask1;
  903.             dst += d_incr;
  904.              }
  905.  
  906.              break;
  907.           case OPCODE(~DST):    /* right->left single-word blit */
  908.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  909.             *dst-- = ~*dst & mask1 | *dst & ~mask1;
  910.             dst += d_incr;
  911.              }
  912.  
  913.              break;
  914.           case OPCODE(~0):    /* right->left single-word blit */
  915.              for (v_cnt = height; v_cnt > 0; v_cnt--) {
  916.             *dst-- = ~0 & mask1 | *dst & ~mask1;
  917.             dst += d_incr;
  918.              }
  919.  
  920.              break;
  921.           case OPCODE(DST):
  922.              break;
  923.            }
  924.  
  925.         }
  926.  
  927.      }
  928.  
  929.       }
  930.  
  931.    }
  932.  
  933. }
  934.